﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using NReports.Data;

namespace NReports.Data {
                         
    /// <summary>
    /// Summary description for XmlDataReader.
    /// </summary>
    public class DataSetDataReader : IDataReader {

        DataSetConnection _connection;
        DataSetCommand _command;
        CommandBehavior _behavior;
        DataTable _table;
        int _tableIndex = -1;

        public DataSetDataReader(CommandBehavior behavior, DataSetConnection conn, DataSetCommand cmd) {

            _connection = conn;
            _command = cmd;
            _behavior = behavior;

            DataSet dataset = new DataSet();
            dataset.ReadXml("d:\\history.xml", XmlReadMode.ReadSchema);

            // database select http://msdn.microsoft.com/en-us/library/t5ce3dyt(vs.71).aspx

            if (cmd.CommandText == "SCHEMA") {

                _table = new DataTable("TABLES");
                _table.Columns.Add(new DataColumn("TABLE_NAME", typeof(string)));
                for (int i = 0; i < dataset.Tables.Count; i++) {
                    var row = _table.NewRow();
                    row["TABLE_NAME"] = dataset.Tables[i].TableName;
                    _table.Rows.Add(row);
                }

            } else {

                for (int i = 0; i < dataset.Tables.Count; i++) {
                    if (cmd.CommandText.ToLower().Contains("from " + dataset.Tables[i].TableName.ToLower())) {
                        _table = dataset.Tables[i];
                    }
                }
            }

        }


        #region IDataReader Members

        public int RecordsAffected {
            get {
                return 0;
            }
        }

        public bool IsClosed {
            get {
                return _connection.IsOpen;
            }
        }

        public bool NextResult() {
            return false;
        }

        public void Close() {
            _table.Clear();
            _table = null;

        }

        public bool Read() {
            if (_tableIndex >= _table.Rows.Count - 1)
                return false;
            _tableIndex++;
            return true;
        }

        public int Depth {
            get {
                // TODO:  Add XmlDataReader.Depth getter implementation
                return 0;
            }
        }

        public DataTable GetSchemaTable() {
            // TODO:  Add XmlDataReader.GetSchemaTable implementation
            return null;
        }

        #endregion

        #region IDisposable Members

        public void Dispose() {
            this.Close();
        }

        #endregion

        #region IDataRecord Members

        public int GetInt32(int i) {
            return Convert.ToInt32(_table.Rows[_tableIndex][i]);
        }

        public object this[string name] {
            get {
                return _table.Rows[_tableIndex][this.GetOrdinal(name)];
            }
        }

        object System.Data.IDataRecord.this[int i] {
            get {
                return _table.Rows[_tableIndex][i];
            }
        }

        public object GetValue(int i) {
            return _table.Rows[_tableIndex][i];
        }

        public bool IsDBNull(int i) {
            return _table.Rows[_tableIndex][i] == null;
        }

        public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) {
            throw new NotImplementedException("GetBytes not implemented.");
        }

        public byte GetByte(int i) {
            return Convert.ToByte(this.GetValue(i));
        }

        public Type GetFieldType(int i) {
            return _table.Columns[i].DataType;
        }

        public decimal GetDecimal(int i) {
            return Convert.ToDecimal(this.GetValue(i));
        }

        public int GetValues(object[] values) {
            int i;
            for (i = 0; i < values.Length; i++) {
                values[i] = i >= this.FieldCount ? System.DBNull.Value : this.GetValue(i);
            }
            return Math.Min(values.Length, this.FieldCount);
        }

        public string GetName(int i) {
            return _table.Columns[i].ColumnName;
        }

        public int FieldCount {
            get {
                return _table.Columns.Count;
            }
        }

        public long GetInt64(int i) {
            return Convert.ToInt64(this.GetValue(i));
        }

        public double GetDouble(int i) {
            return Convert.ToDouble(this.GetValue(i));
        }

        public bool GetBoolean(int i) {
            return Convert.ToBoolean(this.GetValue(i));
        }

        public Guid GetGuid(int i) {
            return new Guid(this.GetString(i));
        }

        public DateTime GetDateTime(int i) {
            return Convert.ToDateTime(this.GetValue(i));
        }

        public int GetOrdinal(string name) {

            for (var i = 0; i < _table.Columns.Count; i++) {
                var col = _table.Columns[i];
                if (col.ColumnName.ToLower() == name.ToLower()) {
                    return i;
                }
            }
            throw new ArgumentException(string.Format("Column '{0}' not known.", name));
        }

        public string GetDataTypeName(int i) {
            return _table.Columns[i].DataType.ToString();
        }

        public float GetFloat(int i) {
            return Convert.ToSingle(this.GetValue(i));
        }

        public IDataReader GetData(int i) {
            throw new NotImplementedException("GetData not implemented.");
        }

        public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) {
            throw new NotImplementedException("GetChars not implemented.");
        }

        public string GetString(int i) {
            return Convert.ToString(this.GetValue(i));
        }

        public char GetChar(int i) {
            return Convert.ToChar(this.GetValue(i));
        }

        public short GetInt16(int i) {
            return Convert.ToInt16(this.GetValue(i));
        }

        #endregion


    }

}
